package util;

import org.w3c.dom.Attr;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import java.io.IOException;

/**
 * Contains a few DOM utility functions.
 */
public class DOMHelper {
	// returns only direct children
	public static NodeList getDirectChildElementsByTagName(Element element, String name) {
		NodeList fullList = element.getElementsByTagName(name);
		class ChildNodeList implements NodeList {
			private Node[] nodes;

			public ChildNodeList(int count) {
				nodes = new Node[count];
			}

			@Override
			public Node item(int index) {
				return nodes[index];
			}

			@Override
			public int getLength() {
				return nodes.length;
			}

			public void set(Node node, int i) {
				nodes[i] = node;
			}
		}

		// count first
		int count = 0;
		for (int i = 0; i < fullList.getLength(); ++i) {
			if (fullList.item(i).getParentNode() == element) {
				++count;
			}
		}

		ChildNodeList childList = new ChildNodeList(count);
		count = 0;
		for (int i = 0; i < fullList.getLength(); ++i) {
			if (fullList.item(i).getParentNode() == element) {
				childList.set(fullList.item(i), count);
				++count;
			}
		}

		return childList;
	}

	public static Element getSingleDirectChildElementByTagName(Element element, String name)
			throws IOException {
		NodeList childList = getDirectChildElementsByTagName(element, name);
		if (childList.getLength() != 1) {
			throw new IOException("Exactly one " + name + " element should be specified");
		}
		return (Element) childList.item(0);
	}

	public static Attr getAttr(Element node, String name)
			throws IOException {
		Attr attr = node.getAttributeNode(name);
		if (attr == null) {
			throw new IOException("Missing attribute " + name + " from node " + node.getTagName());
		}
		return attr;
	}
}
